home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / ddj0492.zip / HANDPRIN.URC / Recognizer / Recognizer.c < prev    next >
Text File  |  1992-03-11  |  4KB  |  167 lines

  1. /* All rights reserved. Copyright Ron Avitzur - 1992
  2. */
  3.  
  4. #include "Recognizer.h"
  5. //#include "Words.h"
  6.  
  7. short Matches[50],Weights[50],Num_Matches;
  8.  
  9.  
  10. short Votes(StrokePattern *p, StrokePtr theStroke);
  11. short Votes(StrokePattern *p, StrokePtr theStroke)
  12.     {
  13.     short type,i,w = 0;
  14.     for (i=NUM_HASHLISTS;i<NUM_FEATURES;i++)
  15.         if (IsInList(p->s[i],theStroke->S[i]))
  16.             w +=  VoteWeight[i];
  17.     return w;
  18.     }
  19.  
  20. short PatternMatch(StrokePattern *p,StrokePtr theStroke);
  21. short PatternMatch(StrokePattern    *p,StrokePtr theStroke)
  22.     {
  23.     register short i,w = 0;
  24.     if (p->is_dot && theStroke->IsDot) return 1000;
  25.     if (p->is_dot != theStroke->IsDot) return 0;
  26.     for (i=0;i<NUM_HASHLISTS;i++)
  27.         if (IsInList(p->s[i],theStroke->S[i]))
  28.             w +=  VoteWeight[i];
  29.     w += Votes(p,theStroke);
  30.     return w;
  31.     }
  32.  
  33.  
  34. short IsInList(List list,register long    n)
  35.     {
  36.     if (list == NIL)
  37.         return 0;
  38.     else {
  39.         register short num = list->num_items;
  40.         register long *p = (long*)list->items;
  41.         while (num--)
  42.             if (n == *p++)
  43.                 return 1;
  44.         }
  45.     return 0;
  46.     }
  47.  
  48. void RecognizeStroke(short whichStroke)
  49.     {
  50.     short    i,index;
  51.     long    item,weight,old_weight;
  52.     GesturePattern *gp;
  53.     StrokePattern  *sp;
  54.     StrokePtr theStroke,previousStroke;
  55.     if (!(Strokes && Strokes->num_items > whichStroke)) return;
  56.     theStroke = (StrokePtr)Strokes->items[whichStroke];
  57.     theStroke->matches = NIL;
  58.     if (!patterns) return;
  59.     
  60.     if (whichStroke == 0) {
  61.         if (Dont_Use_Table) {
  62.             for (i = 0; i < patterns->num_items; i++) {
  63.                 gp = patterns->items[i];
  64.                 sp = gp->strokes->items[0];
  65.                 weight = PatternMatch(sp,theStroke);
  66.                 if (weight)
  67.                     Append(&theStroke->matches,i + (weight<<16));
  68.                 }
  69.             }
  70.         else { /* TODO: NEED TO HANDLE IsDot case here */
  71.             register short possibles[100],weights[100];
  72.             short npossibles = 0;
  73.             long w;
  74.             for (i=0;i<NUM_HASHLISTS;i++)
  75.                 SearchAndAddMatches(possibles,weights,&npossibles,
  76.                                             HashList[i],theStroke->S[i],VoteWeight[i]);
  77.             for (i = 0; i < npossibles; i++) {
  78.                 gp = patterns->items[possibles[i]];
  79.                 sp = gp->strokes->items[0];
  80.                 w = weights[i] + Votes(sp,theStroke);
  81.                 Append(&theStroke->matches,possibles[i] + (w<<16));
  82.                 }
  83.             }
  84.         }
  85.     else {
  86.         previousStroke = Strokes->items[whichStroke - 1];
  87.         if (previousStroke->matches == NIL)
  88.             return;
  89.         for (i = 0; i < previousStroke->matches->num_items; i++) {
  90.             item = (long)previousStroke->matches->items[i];
  91.             index = item & 0xFFFF;
  92.             old_weight = item >> 16;
  93.             gp = patterns->items[index];
  94.             if (gp->strokes->num_items <= whichStroke)
  95.                 continue;
  96.             sp = gp->strokes->items[whichStroke];
  97.             weight = PatternMatch(sp,theStroke);
  98.             if (weight)
  99.                 Append(&theStroke->matches,index + ((weight*(whichStroke+1)+old_weight)<<16));
  100.             }
  101.         }
  102.     }
  103.  
  104.  
  105. static int Compare(long *a,long *b);
  106. static int Compare(long *a,long *b)
  107.     {
  108.     if (*a < *b) return 1;
  109.     if (*a > *b) return -1;
  110.     return 0;
  111.     }
  112.  
  113.  
  114. short FindBestMatch(void);
  115. short FindBestMatch()
  116.     {
  117.     short i,n,best = 0,guess = -1;
  118.     StrokePtr theStroke = Strokes->items[Strokes->num_items - 1];
  119.  
  120.     Num_Matches = 0;
  121.     n = theStroke->matches->num_items;
  122.     if (n == 0)
  123.         return -1;
  124. #if 0
  125.     qsort(theStroke->matches->items,n,sizeof(long),(void*)Compare);
  126.     for (i = 0; i < n; i++) {
  127.         short index  = (long)theStroke->matches->items[i] & 0xFFFF;
  128.         short weight = (long)theStroke->matches->items[i] >> 16;
  129.         GesturePattern *gp = patterns->items[index];
  130.         if (Strokes->num_items == gp->strokes->num_items && weight >= min_weight) {
  131.             Matches[Num_Matches] = gp->code;
  132.             Weights[Num_Matches++] = weight;
  133.             }
  134.         }
  135.     if (Num_Matches)
  136.             return Matches[0];
  137.     else    return -1;
  138. #else
  139.     for (i = 0; i < n; i++) {
  140.         short index  = (long)theStroke->matches->items[i] & 0xFFFF;
  141.         short weight = (long)theStroke->matches->items[i] >> 16;
  142.         GesturePattern *gp = patterns->items[index];
  143.         if (Strokes->num_items == gp->strokes->num_items && weight >= best) {
  144.             guess = gp->code;
  145.             best = weight;
  146.             }
  147.         }
  148.     return guess;
  149. #endif
  150.     }
  151.  
  152. short Recognize()
  153.     {
  154.     StrokePtr theStroke;
  155.     
  156.     if (Strokes == NIL) return 0;
  157.     theStroke = Strokes->items[Strokes->num_items - 1];
  158.     if (theStroke->matches == NIL || theStroke->matches->num_items == 0)
  159.         return 0;
  160.     else {
  161.         GesturePattern *gp;
  162.         short code = FindBestMatch();
  163.         if (code == -1) return 0;
  164.         return code;
  165.         }
  166.     }
  167.